package com.cy.pj.sys.service.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@Aspect
public class SysTimeAspect {
    @Pointcut("@annotation(com.cy.common.annotation.RequiredTime)")
    public void doTime() {
    }

    //目标业务执行之前执行,存放数据过滤或预处理操作
    // 通过joinPoint对象 除了Around对象
    @Before("doTime()")
    public void doBefore() {
        System.out.println("@Before");
    }

    //目标业务执行之后,存放资源释放操作
    @After("doTime()")
    public void doAfter() {
        System.out.println("@After");
    }

    //在目标方法正常结束时执行 ,两者,二者存其一.
    //一般进行缓存更新操作(清楚 cache.clear(),更新)
    @AfterReturning("doTime()")
    public void doAfterReturning() {
        System.out.println("@AfterReturning");
    }

    //在目标方法异常时执行 两者,二者存其一
    //在此方法中可以进行错误日志记录,设置报警.
    @AfterThrowing("doTime()")
    public void doAfterThrowing() {
        System.out.println("@doAfterThrowing");
    }

    @Around("doTime()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
        System.out.println("@Around.before");
        try {
            //proced执行逻辑  ->本类其他before,其他切面before,目标方法,当前或其他切面的后续通知方法
            Object result = proceedingJoinPoint.proceed();
            System.out.println("@Around.AfterReturning");
            return result;
        } catch (Throwable e) {
            System.out.println("@Around.AfterThrowing");
            throw e;
        } finally {
            //finaly属于必定执行
            System.out.println("@Around.After");
        }
    }
}

